<template>
	<view class="uni-badge--x">
		<slot />
		<text
			v-if="text"
			:class="classNames"
			:style="[badgeWidth, positionStyle, customStyle, dotStyle]"
			class="uni-badge"
			@click="onClick()"
			>{{ displayValue }}</text
		>
	</view>
</template>

<script>
/**
 * Badge 数字角标
 * @description 数字角标一般和其它控件（列表、9宫格等）配合使用，用于进行数量提示，默认为实心灰色背景
 * @tutorial https://ext.dcloud.net.cn/plugin?id=21
 * @property {String} text 角标内容
 * @property {String} size = [normal|small] 角标内容
 * @property {String} type = [info|primary|success|warning|error] 颜色类型
 * 	@value info 灰色
 * 	@value primary 蓝色
 * 	@value success 绿色
 * 	@value warning 黄色
 * 	@value error 红色
 * @property {String} inverted = [true|false] 是否无需背景颜色
 * @property {Number} maxNum 展示封顶的数字值，超过 99 显示 99+
 * @property {String} absolute = [rightTop|rightBottom|leftBottom|leftTop] 开启绝对定位, 角标将定位到其包裹的标签的四角上
 * 	@value rightTop 右上
 * 	@value rightBottom 右下
 * 	@value leftTop 左上
 * 	@value leftBottom 左下
 * @property {Array[number]} offset	距定位角中心点的偏移量，只有存在 absolute 属性时有效，例如：[-10, -10] 表示向外偏移 10px，[10, 10] 表示向 absolute 指定的内偏移 10px
 * @property {String} isDot = [true|false] 是否显示为一个小点
 * @event {Function} click 点击 Badge 触发事件
 * @example <uni-badge text="1"></uni-badge>
 */

export default {
	name: 'UniBadge',
	emits: ['click'],
	props: {
		type: {
			type: String,
			default: 'error',
		},
		inverted: {
			type: Boolean,
			default: false,
		},
		isDot: {
			type: Boolean,
			default: false,
		},
		maxNum: {
			type: Number,
			default: 99,
		},
		absolute: {
			type: String,
			default: '',
		},
		offset: {
			type: Array,
			default() {
				return [0, 0]
			},
		},
		text: {
			type: [String, Number],
			default: '',
		},
		size: {
			type: String,
			default: 'small',
		},
		customStyle: {
			type: Object,
			default() {
				return {}
			},
		},
	},
	data() {
		return {}
	},
	computed: {
		width() {
			return String(this.text).length * 8 + 12
		},
		classNames() {
			const { inverted, type, size, absolute } = this
			return [
				inverted ? 'uni-badge--' + type + '-inverted' : '',
				'uni-badge--' + type,
				'uni-badge--' + size,
				absolute ? 'uni-badge--absolute' : '',
			].join(' ')
		},
		positionStyle() {
			if (!this.absolute) return {}
			let w = this.width / 2,
				h = 10
			if (this.isDot) {
				w = 5
				h = 5
			}
			const x = `${-w + this.offset[0]}px`
			const y = `${-h + this.offset[1]}px`

			const whiteList = {
				rightTop: {
					right: x,
					top: y,
				},
				rightBottom: {
					right: x,
					bottom: y,
				},
				leftBottom: {
					left: x,
					bottom: y,
				},
				leftTop: {
					left: x,
					top: y,
				},
			}
			const match = whiteList[this.absolute]
			return match ? match : whiteList['rightTop']
		},
		badgeWidth() {
			return {
				width: `${this.width}px`,
			}
		},
		dotStyle() {
			if (!this.isDot) return {}
			return {
				width: '10px',
				height: '10px',
				borderRadius: '10px',
			}
		},
		displayValue() {
			const { isDot, text, maxNum } = this
			return isDot ? '' : Number(text) > maxNum ? `${maxNum}+` : text
		},
	},
	methods: {
		onClick() {
			this.$emit('click')
		},
	},
}
</script>

<style lang="scss">
$uni-primary: #2979ff !default;
$uni-success: #4cd964 !default;
$uni-warning: #f0ad4e !default;
$uni-error: #dd524d !default;
$uni-info: #909399 !default;

$bage-size: 12px;
$bage-small: scale(0.8);

.uni-badge--x {
	/* #ifdef APP-NVUE */
	// align-self: flex-start;
	/* #endif */
	/* #ifndef APP-NVUE */
	display: inline-block;
	/* #endif */
	position: relative;
}

.uni-badge--absolute {
	position: absolute;
}

.uni-badge--small {
	transform: $bage-small;
	transform-origin: center center;
}

.uni-badge {
	/* #ifndef APP-NVUE */
	display: flex;
	overflow: hidden;
	box-sizing: border-box;
	/* #endif */
	justify-content: center;
	flex-direction: row;
	height: 20px;
	line-height: 18px;
	color: #fff;
	border-radius: 100px;
	background-color: $uni-info;
	background-color: transparent;
	border: 1px solid #fff;
	text-align: center;
	font-family: 'Helvetica Neue', Helvetica, sans-serif;
	font-size: $bage-size;
	/* #ifdef H5 */
	z-index: 999;
	cursor: pointer;
	/* #endif */

	&--info {
		color: #fff;
		background-color: $uni-info;
	}

	&--primary {
		background-color: $uni-primary;
	}

	&--success {
		background-color: $uni-success;
	}

	&--warning {
		background-color: $uni-warning;
	}

	&--error {
		background-color: $uni-error;
	}

	&--inverted {
		padding: 0 5px 0 0;
		color: $uni-info;
	}

	&--info-inverted {
		color: $uni-info;
		background-color: transparent;
	}

	&--primary-inverted {
		color: $uni-primary;
		background-color: transparent;
	}

	&--success-inverted {
		color: $uni-success;
		background-color: transparent;
	}

	&--warning-inverted {
		color: $uni-warning;
		background-color: transparent;
	}

	&--error-inverted {
		color: $uni-error;
		background-color: transparent;
	}
}
</style>
